﻿/* 
* Copyright (c) 2010, The University of Texas at Austin
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, 
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, 
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, 
* this list of conditions and the following disclaimer in the documentation and/or other materials 
* provided with the distribution.
*
* Neither the name of The University of Texas at Austin nor the names of its contributors may be 
* used to endorse or promote products derived from this software without specific prior written 
* permission.
* 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using Bio.Data.Interfaces;
using Bio.Views.Structure.Editor.Internal.Selection;
using Bio.Views.Structure.Editor.Internal.Rendering.Visuals;

namespace Bio.Views.Structure.Editor.Internal.Editing
{
    public enum RotationType { ToAngleDegrees, ByAngleDegrees }
    public enum TranslationType { ToLocation, ByOffset }
    public enum ExecutionMode { All, Selected, Filtered, FilteredRange }
    
    public class TranslateSelectedStructureElementEventArgs : EventArgs
    {
        public Point Translation { get; private set; }
        public TranslationType Mode { get; private set; }

        public TranslateSelectedStructureElementEventArgs(Point translation, TranslationType mode)
        {
            Translation = translation;
            Mode = mode;
        }
    }

    public class RotateSelectedStructureElementEventArgs : EventArgs
    {
        public double RotationInDegrees { get; private set; }
        public RotationType Mode { get; private set; }

        public RotateSelectedStructureElementEventArgs(double angle, RotationType mode)
        {
            RotationInDegrees = angle;
            Mode = mode;
        }
    }

    public class ResizeStructureElementEventArgs : EventArgs
    {
        public ExecutionMode Mode { get; private set; }
        public StructureElementSelectionMode ElementType { get; private set; }
        public double Width { get; private set; }
        public double Padding { get; private set; }
        public bool HaveWidth { get; private set; }
        public bool HavePadding { get; private set; }

        public void SetWidth(double value)
        {
            Width = value;
            HaveWidth = true;
        }

        public void SetPadding(double value)
        {
            Padding = value;
            HavePadding = true;
        }

        public void UnsetWidth()
        {
            HaveWidth = false;
            Width = -1.0;
        }

        public void UnsetPadding()
        {
            HavePadding = false;
            Padding = -1.0;
        }

        public ResizeStructureElementEventArgs(ExecutionMode mode, StructureElementSelectionMode elementType)
        {
            Mode = mode;
            ElementType = elementType;
            UnsetPadding();
            UnsetWidth();
        }

        public ResizeStructureElementEventArgs()
        {
            Mode = ExecutionMode.Selected;
            UnsetPadding();
            UnsetWidth();
        }
    }

    public class ProvidedValueEventArgs : EventArgs
    {
        public double Value { get; private set; }

        public ProvidedValueEventArgs(double value)
        {
            Value = value;
        }
    }

    public class SelectStructureElementContainingNucleotideIndexEventArgs : EventArgs
    {
        public int NucleotideIndex { get; private set; }

        public SelectStructureElementContainingNucleotideIndexEventArgs(int nucleotideIndex)
        {
            NucleotideIndex = nucleotideIndex;
        }
    }

    public class EditStructureElementPropertiesEventArgs : EventArgs
    {
        public ExecutionMode Mode { get; private set; }
        public StructureElementSelectionMode ElementType { get; private set; }
        public StructureElementPropertyChangeSet ChangeSet { get; private set; }
        public List<IBioSymbol> NucleotideFilter { get; private set; }
        public List<string> BasePairFilter { get; private set; }

        public EditStructureElementPropertiesEventArgs(StructureElementPropertyChangeSet changeSet)
        {
            Mode = ExecutionMode.Selected;
            ChangeSet = changeSet;
        }

        public EditStructureElementPropertiesEventArgs(StructureElementSelectionMode elementType,
            StructureElementPropertyChangeSet changeSet)
        {
            Mode = ExecutionMode.All;
            ChangeSet = changeSet;
            ElementType = elementType;
        }

        public EditStructureElementPropertiesEventArgs(ExecutionMode mode, StructureElementPropertyChangeSet changeSet, List<IBioSymbol> nucleotideFilter)
        {
            Mode = mode;
            Debug.Assert(Mode == ExecutionMode.Filtered || Mode == ExecutionMode.FilteredRange);
            ChangeSet = changeSet;
            ElementType = StructureElementSelectionMode.Nucleotide;
            NucleotideFilter = nucleotideFilter;
        }

        public EditStructureElementPropertiesEventArgs(StructureElementPropertyChangeSet changeSet, List<string> basePairFilter)
        {
            Mode = ExecutionMode.Filtered;
            ChangeSet = changeSet;
            ElementType = StructureElementSelectionMode.BasePair;
            BasePairFilter = basePairFilter;
        }
    }

    public class CreateStructureElementEventArgs : EventArgs
    {
        public int BPFivePrime { get; private set; }
        public int BPThreePrime { get; private set; }
        public int HelixFivePrimeEnd { get; private set; }
        public bool CreateHelix { get; private set; }

        public CreateStructureElementEventArgs(int bpFivePrime, int bpThreePrime, int helixFivePrimeEnd)
        {
            CreateHelix = true;
            BPFivePrime = bpFivePrime;
            BPThreePrime = bpThreePrime;
            HelixFivePrimeEnd = helixFivePrimeEnd;
        }

        public CreateStructureElementEventArgs(int bpFivePrime, int bpThreePrime)
        {
            CreateHelix = false;
            BPFivePrime = bpFivePrime;
            BPThreePrime = bpThreePrime;
        }
    }

    public class MixedRangeEditSetEventArgs : EventArgs
    {
        public List<NucleotideStructureElementVisualComponent> ModifiedNucleotides { get; private set; }
        public List<BasePairStructureElementVisualComponent> ModifiedBasePairs { get; private set; }

        public MixedRangeEditSetEventArgs(List<NucleotideStructureElementVisualComponent> modifiedNucleotides, List<BasePairStructureElementVisualComponent> modifiedBasePairs)
        {
            ModifiedNucleotides = modifiedNucleotides;
            ModifiedBasePairs = modifiedBasePairs;
        }

        public MixedRangeEditSetEventArgs(List<NucleotideStructureElementVisualComponent> modifiedNucleotides)
        {
            ModifiedNucleotides = modifiedNucleotides;
            ModifiedBasePairs = new List<BasePairStructureElementVisualComponent>();
        }

        public MixedRangeEditSetEventArgs(List<BasePairStructureElementVisualComponent> modifiedBasePairs)
        {
            ModifiedNucleotides = new List<NucleotideStructureElementVisualComponent>();
            ModifiedBasePairs = modifiedBasePairs;
        }
    }
}